import * as qiniu from "qiniu-js";
import ajax from "./request";
import { ref } from "vue";
// import {IUploadResult,IUploadFile, IQiniuToken} from "@my/types"

import type {
  UploadRequestOptions,
  UploadRawFile
} from "element-plus";

/**
 * 通过异步请求获取七牛云上传token
 * @returns 
 */
function getToken() {
  return ajax("/resource/getToken");
}

/**
 * 添加七牛云上传方法
 * @param formData 表单对象，如果调用handleHttpRequest完成上传，上传结果会填入到该对象的属性中。
 * @returns 
 */
export default function setupUpload(formData?: IUploadFile): IUploadResult {

  // 进度条的值
  const progressNum = ref(0);

  /**
   * 调用七牛云异步上传，上传成功后会将数据填入传入的formData的属性中。
   * 该方法可以直接用在ElementPlus中el-upload的http-request属性上。
   * @param options 上传对象（可以使用elementPlus的文件上传对象）
   */
  function handleHttpRequest(options: UploadRequestOptions): void {
    if (formData) {
      asyncRequest(options).then(res => {
        Object.assign(formData, res);
      });
    }
  }

  /**
   * 进行七牛云异步上传，返回Promise对象
   * @param options elementPlus的上传对象
   * @returns 
   */
  async function asyncRequest(options: UploadRequestOptions): Promise<IUploadFile> {
    let uploadOptions: IQiniuToken;
    // file: http的formData对象
    const file = <UploadRawFile>options.file;

    try {
      // 通过异步请求，访问后端API，获取上传token
      const res = await getToken();
      uploadOptions = res.data.result_data;
    } catch {
      alert({ type: "error", message: "获取token发生网络错误" });
      return Promise.reject(null);
    }

    if (uploadOptions == null) {
      alert({ type: "error", message: "无法获取上传token" });
      return Promise.reject(null);
    }

    // 文件原名
    const name = file.name;
    // 通过原名获取扩展名： logo.png => png
    const arr = name.split(".")
    let suffix = "";
    if (arr.length >= 2) {
      suffix = "." + arr[arr.length - 1];
    }

    // 七牛云上传参数
    // uid：elemetPlus封装的uuid。唯一码生成方式：要么使用elementPlus的唯一码，要么使用时间戳
    const uid = file.uid ? file.uid : new Date().getTime();

    // 计算文件key，文件key是七牛云的文件唯一标识，如果key一样，会覆盖掉之前的文件，访问文件需要域名+key
    // 通过唯一码 + 后缀名生成key
    const key = `07adm-${uid}${suffix}`;

    // 七牛云上传配置参数
    const config = {
      // 是否使用直传
      forceDirect: true,
      // 是否使用域名加速
      useCdnDomain: true,
      // 华南地区
      region: qiniu.region.z2,
    };

    // 七牛云上传配置参数（扩展参数）
    const putExtra = {
      fname: file.name, // 文件原文件名
      params: {}, // 放置自定义变量
      // mimeType: ["video/mp4", "video/ogg", "video/webm"], // 上传文件限制，null为不限制；限制类型放在数组中['image/png',"image/gif"]
      mineType: null,
    };

    // 上传开始，进度条归零
    progressNum.value = 0;

    // 正式上传，返回一个监听对象
    const observable = qiniu.upload(file, key, uploadOptions.token, putExtra, config);
    return new Promise((resolve, reject) => {
      // 提交上传
      observable.subscribe({
        // 回调函数，上传过程，回传上传进度值
        next(resProgress) {
          progressNum.value = Math.floor(resProgress.total.percent);
        },
        // 上传失败
        error(res) {
          alert({
            type: "warning",
            message: "上传失败",
          });
          reject(null);
        },
        // 上传成功
        complete(res) {
          alert({
            type: "success",
            message: "上传成功",
          });

          setTimeout(() => {
            progressNum.value = 0;
          }, 1500);

          // 成功后resolve结果
          resolve({
            file_path: `${uploadOptions.remoteAddr}/${res.key}`,
            file_name: file.name,
            content_length: file.size,
            content_type: file.type
          })
        },
      });
    })
  }
  return { handleHttpRequest, asyncRequest, progressNum }
}